﻿using System;
using System.Linq;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using AForge.Imaging;
using ImageProcessor.Shared;
using ImageProcessor.Shared.ImageExtensions;

namespace ImageProcessor.Tim
{
    public class MedianFilterVM : ImageProcessorBaseVM
    {
        private int _maskDimension;
        private ImageSource _resultImage;               

        public MedianFilterVM(MainViewModel mainVM) : base(mainVM)
        {
            MaskDimension = 3;
        }

        public int MaskDimension
        {
            get { return _maskDimension; }
            set
            {
                if(_maskDimension == value)
                    return;
                _maskDimension = value;
                OnPropertyChanged("MaskDimension");
            }
        }

        public ImageSource ResultImage
        {
            get { return _resultImage; }
            private set
            {
                if (_resultImage == value)
                    return;
                _resultImage = value;
                OnPropertyChanged("ResultImage");
            }
        }

        protected override void Execute(object obj)
        {
//            Dx:=CN div 2;
//              for i:=0 to BitMap.Width - 1 - CN do   //движение маски по горизонтали
//                for j:=0 to BitMap.Height - 1 - CN do  //движение маски по вертикали
//                  begin
//                    //заносим значения пикселей в вектор MyMas
//                    Index:=1;
//                    for k:=i to i + (CN - 1) do
//                      for s:=j to j + (CN - 1) do
//                        begin
//                          MyMas[Index]:=BitMap.Canvas.Pixels[k,s];
//                          Inc(Index);
//                        end;
//                      n:=Sort(MyMas);  //сортируем вектор с возвратом значения среднего элемента
//                      BitMap.Canvas.Pixels[i+Dx, j+Dx]:=n;
//                  end;
            var bitmap = new WriteableBitmap((BitmapSource) MainVM.SourceImage.Clone());
            var resultBitmap = new WriteableBitmap((BitmapSource) MainVM.SourceImage.Clone());

            var mask = new Color[(int) Math.Pow(MaskDimension, 2)];
            var dx = (int) Math.Round(MaskDimension/2d, MidpointRounding.AwayFromZero) - 1;

            var shumes = new[] {0, 255};

            for(var i = 0; i < bitmap.Width ; i++)
            for(var j = 0; j < bitmap.Height ; j++)
            {
                byte grayLevel = bitmap.GetPixel(i, j).R;

                if (shumes.Contains(grayLevel))
                {
                    var index = 0;

                    for (var k = i - dx; k <= i + dx; k++)
                        for (var s = j - dx; s <= j + dx; s++)
                        {
                            var newK = k;
                            var newS = s;
                            if (k < 0)
                                newK = 0;
                            if (k > 255)
                                newK = 255;
                            if (s < 0)
                                newS = 0;
                            if (s > 255)
                                newS = 255;
                            
                            Color pixelColor = bitmap.GetPixel(newK, newS);
                            mask[index] = pixelColor;
                            index++;
                        }
                    var orderedMask = mask.OrderBy(color => color.R).ToList();
                    int centerIndex = orderedMask.Count/2;
                    var centerPixel = orderedMask[centerIndex];

                    resultBitmap.SetPixel(i, j, centerPixel);
                }
            }

            ResultImage = resultBitmap;
        }

        protected override bool CanExecute(object obj)
        {
            return MainVM.SourceImage != null;
        }
    }
}